package com.wangshaoyu.music_player.controller;

import com.wangshaoyu.music_player.data_object.AlbumDo;
import com.wangshaoyu.music_player.data_object.TrackDo;
import com.wangshaoyu.music_player.repository.AlbumRepo;
import com.wangshaoyu.music_player.repository.RelationRepo;
import com.wangshaoyu.music_player.repository.TrackRepo;
import com.wangshaoyu.music_player.service.AlbumService;
import com.wangshaoyu.music_player.session_object.UserSO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/studio/album")
public class StudioAlbumJsonController {
    private final AlbumRepo albumRepo;
    private final TrackRepo trackRepo;
    private final RelationRepo relationRepo;
    private final AlbumService albumService;

    @Autowired
    public StudioAlbumJsonController(AlbumRepo albumRepo, TrackRepo trackRepo, RelationRepo relationRepo, AlbumService albumService) {
        this.albumRepo = albumRepo;
        this.trackRepo = trackRepo;
        this.relationRepo = relationRepo;
        this.albumService = albumService;
    }

    @Data
    public static class AlbumView {
        public Integer aid;
        public String title;
        public String cover;
        public String state;
        public Integer count;

        public AlbumView(AlbumDo albumDo) {
            this.aid = albumDo.aid;
            this.title = albumDo.title;
            this.cover = albumDo.cover;
            this.state = toState(albumDo.state);
        }

        private String toState(int state) {
            switch (state) {
                case 1: return "未发布";
                case 2: return "已发布";
                case 0: return "已下线";
                default: return "错误状态";
            }
        }
    }

    @Data
    public static class AlbumListView {
        public UserSO currentUser;
        public List<AlbumView> albumList;
    }

    @GetMapping("/list.json")
    public AlbumListView list(HttpServletRequest request) {
        AlbumListView view = new AlbumListView();
        HttpSession session = request.getSession(false);
        if (session != null) {
            view.currentUser = (UserSO) session.getAttribute("currentUser");
            if (view.currentUser != null) {
                view.albumList = albumService.list(view.currentUser);
            }
        }

        return view;
    }

    @Data
    public static class TrackView {
        public Integer tid;
        public String title;

        public TrackView(TrackDo trackDo) {
            this.tid = trackDo.tid;
            this.title = trackDo.title;
        }
    }

    @Data
    public static class RelateView {
        public UserSO currentUser;
        public List<TrackView> trackList;
    }

    @GetMapping("/relate.json")
    public RelateView relatedTrackList(HttpServletRequest request, int aid) {
        RelateView view = new RelateView();
        HttpSession session = request.getSession(false);
        if (session != null) {
            view.currentUser = (UserSO) session.getAttribute("currentUser");
            if (view.currentUser != null) {
                view.trackList = new ArrayList<>();
                AlbumDo albumDo = albumRepo.selectOneByAid(aid);
                if (albumDo == null) {
                    log.error("要绑定的专辑不存在: aid = {}", aid);
                    return view;
                }

                if (!albumDo.uid.equals(view.currentUser.uid)) {
                    log.error("要绑定的专辑不属于这个用户: aid = {}, album.uid = {}, currentUser.uid = {}", aid, albumDo.uid, view.currentUser.uid);
                    return view;
                }

                List<Integer> tidList = relationRepo.selectTidListByAid(aid);
                if (tidList.isEmpty()) {
                    return view;
                }

                List<TrackDo> trackDoList = trackRepo.selectListByTidList(tidList);
                Map<Integer, TrackDo> tidToTrackMap = new HashMap<>();
                for (TrackDo trackDo : trackDoList) {
                    tidToTrackMap.put(trackDo.tid, trackDo);
                }

                for (Integer tid : tidList) {
                    TrackDo trackDo = tidToTrackMap.get(tid);
                    TrackView trackView = new TrackView(trackDo);
                    view.trackList.add(trackView);
                }
            }
        }

        return view;
    }

    @Data
    public static class CandidateView {
        public UserSO currentUser;
        List<TrackView> trackList;
    }

    @GetMapping("/candidate-list.json")
    public CandidateView candidateList(HttpServletRequest request, int aid) {
        CandidateView view = new CandidateView();
        HttpSession session = request.getSession(false);
        if (session != null) {
            view.currentUser = (UserSO) session.getAttribute("currentUser");
            if (view.currentUser != null) {
                view.trackList = new ArrayList<>();
                AlbumDo albumDo = albumRepo.selectOneByAid(aid);
                if (albumDo == null) {
                    log.error("要绑定的专辑不存在: aid = {}", aid);
                    return view;
                }

                if (!albumDo.uid.equals(view.currentUser.uid)) {
                    log.error("要绑定的专辑不属于这个用户: aid = {}, album.uid = {}, currentUser.uid = {}", aid, albumDo.uid, view.currentUser.uid);
                    return view;
                }

                List<Integer> tidList = relationRepo.selectTidListByAid(aid);
                List<TrackDo> trackDoList;
                if (tidList.isEmpty()) {
                    trackDoList = trackRepo.selectListByUid(view.currentUser.uid);
                } else {
                    trackDoList = trackRepo.selectListByUidAndNotInTidList(view.currentUser.uid, tidList);
                }

                view.trackList = new ArrayList<>();
                for (TrackDo trackDo : trackDoList) {
                    TrackView trackView = new TrackView(trackDo);
                    view.trackList.add(trackView);
                }
            }
        }

        return view;
    }
}
